package com.lzx.applib.widget;

import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.widget.LinearLayout;
import android.widget.NumberPicker;
import android.widget.NumberPicker.OnValueChangeListener;

import com.lzx.applib.R;
import com.lzx.applib.utils.StreamUtil;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;


public class CitySelecter extends LinearLayout {

    public static final String UNSELECTED = "--";

    public NumberPicker provincePicker, cityPicker, countyPicker;

    private static CityProvider provider;

    public CitySelecter(Context context) {
        this(context, null);
    }

    public CitySelecter(Context context, AttributeSet attrs) {
        super(context, attrs);

        if (provider == null)
            provider = new CityProvider();

        setWeightSum(3);
        setOrientation(HORIZONTAL);

        provincePicker = new NumberPicker(getContext());
        cityPicker = new NumberPicker(getContext());
        countyPicker = new NumberPicker(getContext());

        initPicker(provincePicker);
        initPicker(cityPicker);
        initPicker(countyPicker);

        resetProvince();
    }

    public void initPicker(NumberPicker picker) {
        LayoutParams lp = new LayoutParams(1, LayoutParams.MATCH_PARENT);
        lp.weight = 1;

        picker.setOnValueChangedListener(onValueChangeListener);
        addView(picker, lp);
    }

    public void resetProvince() {
        currentProvince = 0;

        initPicker(provincePicker, provider.getProvince());
        resetCity(currentProvince);
    }

    public void resetCity(int provinceIndex) {
        currentCity = 0;

        String[] citys = provider.getCity(provinceIndex);
        initPicker(cityPicker, citys);

        resetCounty(provinceIndex, 0);
    }

    public void resetCounty(int provinceIndex, int cityIndex) {
        currentCounty = 0;

        String[] countys = provider.getCounty(provinceIndex, cityIndex);
        initPicker(countyPicker, countys);
    }

    OnValueChangeListener valueChangeListener;

    public void setOnValueChangeListener(OnValueChangeListener listener) {
        this.valueChangeListener = listener;
    }

    int currentProvince = 0;
    int currentCity = 0;
    int currentCounty = 0;

    public String getSelectedCity() {
        String province = provider.getProvince()[currentProvince];
        String city = provider.getCity(currentProvince)[currentCity];
        String county = provider.getCounty(currentProvince, currentCity)[currentCounty];

        province = getShowText(province);
        city = getShowText(city);
        county = getShowText(county);

        String result = "";
        if (province != null)
            result += province;
        if (city != null)
            result += " " + city;
        if (county != null)
            result += " " + county;

        return result;
    }

    private String getShowText(String place) {
        if (TextUtils.isEmpty(place) || TextUtils.equals(UNSELECTED, place))
            return null;
        return place;
    }

    OnValueChangeListener onValueChangeListener = new OnValueChangeListener() {
        @Override
        public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
            // TODO Auto-generated method stub
            if (oldVal == newVal) return;
            if (picker == provincePicker) {
                resetCity(newVal);
                currentProvince = newVal;
            } else if (picker == cityPicker) {
                resetCounty(currentProvince, newVal);
                currentCity = newVal;
            } else if (picker == countyPicker) {
                currentCounty = newVal;
            }

            if (valueChangeListener != null)
                valueChangeListener.onValueChange(picker, oldVal, newVal);
        }
    };


    public void initPicker(NumberPicker picker, String[] displayedValues) {
        picker.setMaxValue(0);
        picker.setMinValue(0);

        picker.setDisplayedValues(displayedValues);
        picker.setMaxValue(displayedValues.length - 1);
        picker.setMinValue(0);
        picker.setValue(0);
        picker.setDescendantFocusability(FOCUS_BLOCK_DESCENDANTS);
    }


    public class CityProvider {

        private Map<String, List<String>> _provinceMap = new LinkedHashMap<String, List<String>>();
        private Map<String, List<String>> _cityMap = new LinkedHashMap<String, List<String>>();

        public String[] provinces;
        public Map<String, String[]> provinceMap = new LinkedHashMap<String, String[]>();
        public Map<String, String[]> cityMap = new LinkedHashMap<String, String[]>();

        public CityProvider() {
            String[] data = null;
            try {
                InputStream in = getResources().openRawResource(R.raw.city);
                data = StreamUtil.streamToStringArray(in);
                StreamUtil.closeSafely(in);
            } catch (Exception e) {
                e.printStackTrace();
            }

            addtoMap(_provinceMap, UNSELECTED, UNSELECTED);
            addtoMap(_cityMap, UNSELECTED, UNSELECTED);

            String[] citys = data;
            for (String city : citys) {
                if (TextUtils.isEmpty(city))
                    continue;
                String[] temp = city.trim().split(" ");

                if (temp.length < 2)
                    continue;

                addtoMap(_provinceMap, temp[0], temp[1]);
                addtoMap(_cityMap, temp[1], temp.length == 3 ? temp[2] : UNSELECTED);

            }

            rebuildData();
        }

        private void addtoMap(Map<String, List<String>> map, String key, String value) {
            List<String> list = map.get(key);
            if (list == null) {
                list = new ArrayList<String>();
                map.put(key, list);
            }
            if (value != null && !list.contains(value))
                list.add(value);
        }


        private void rebuildData() {
            provinces = _provinceMap.keySet().toArray(new String[0]);
            for (String key : _provinceMap.keySet()) {
                String[] value = _provinceMap.get(key).toArray(new String[0]);
                provinceMap.put(key, value);
            }
            for (String key : _cityMap.keySet()) {
                String[] value = _cityMap.get(key).toArray(new String[0]);
                cityMap.put(key, value);
            }
        }

        public String[] getProvince() {
            return provinces;
        }

        public String[] getCity(int provinceIndex) {
            return provinceMap.get(provinces[provinceIndex]);
        }

        public String[] getCounty(int provinceIndex, int cityIndex) {
            String city = provinceMap.get(provinces[provinceIndex])[cityIndex];
            return cityMap.get(city);
        }
    }

    public static void setDividerColorAndHeight(NumberPicker picker, int color, int height) {
        try {
            Field field1 = NumberPicker.class.getDeclaredField("mSelectionDivider");
            Field field2 = NumberPicker.class.getDeclaredField("mSelectionDividerHeight");

            field1.setAccessible(true);
            field2.setAccessible(true);

            ColorDrawable colorDrawable = new ColorDrawable(color);
            field1.set(picker, colorDrawable);
            field2.set(picker, height);

        } catch (Exception e) {
            // TODO: handle exception
        }
    }

}
